function Statistics(entrance, exit, required) {
	this.entrance = entrance;
	this.exit = exit;
	this.required = required;

	this.__defineGetter__("released", function() {
		return this.entrance.released;
	});

	this.__defineGetter__("saved", function() {
		return this.exit.saved;
	});

	this.hasWon = function() {
		return this.hasFinished() && this.exit.saved >= this.required;
	};

	this.hasLost = function() {
		return this.hasFinished() && this.exit.saved < this.required;
	};

	this.hasFinished = function() {
		return this.exit.saved >= this.required;
	};

	this.percentSaved = function() {
		return 100 * this.exit.saved / this.entrance.released;
	}
}

function World() {
	this.stepping = 0;

	this.canvas = createCanvasOverlay("100");
	this.context;
	this.terrain = [];
	this.robots = [];
	this.droids = [];
	this.width;
	this.height;
	this.terrainManager;
	this.entrance;
	this.exit;
	this.statistics;
	this.numRequired = 1;
	this.selectedX = 0;
	this.selectedY = 0;

	this.init = function() {
		this.context = this.canvas.getContext('2d');
		this.width = this.canvas.width;
		this.height = this.canvas.height;

		this.terrainManager = new TerrainManager(this.width, this.height,
				createDivOverlay("150"));
		this.entrance = new Entrance(540, 0, 100, 0);
		this.exit = new Exit(700, 110);

		this.statistics = new Statistics(this.entrance, this.exit,
				this.numRequired);

		// this.droids.push(new Droid(800, 1200, this));
		this.droids.push(new Faller(600, 300, 0, 0, 1000, 0, [], this, null));
	};

	this.updateSelectedDroid = function() {
		for ( var i = 0; i < this.droids.length; i++) {
			this.droids[i].selected = false;
		}
		for ( var i = this.droids.length - 1; i >= 0; i--) {
			var droid = this.droids[i];
			if (containsPoint(this.selectedX, this.selectedY, droid.x, droid.y,
					droid.width, droid.height) && droid.isSelectable()) {
				this.droids[i].selected = true;
				break;
			}
		}
	};

	this.step = function() {
		this.updateSelectedDroid();

		for ( var i = 0, len = this.droids.length; i < len; ++i) {
			this.droids[i] = this.droids[i].transform();
		}

		for ( var i = 0, len = this.droids.length; i < len; ++i) {
			this.droids[i].step(this.terrainManager);
		}
		this.terrainManager.step();

		this.entrance.step(this);
		this.exit.step(this);

		this.stepping++;
	};

	this.clear = function() {
		for ( var i = 0; i < this.droids.length; i++) {
			this.droids[i].clear(this.context);
		}
	};

	this.draw = function() {
		this.terrainManager.draw(this.context);

		for ( var i = 0; i < this.droids.length; i++) {
			this.droids[i].draw(this.context, this.width, this.height,
					this.stepping);
		}
		
		for ( var i = 0; i < this.droids.length; i++) {
			this.droids[i].drawSelection(this.context);
		}

		this.entrance.draw(this.context);
		this.exit.draw(this.context);

	};

	this.addDroid = function(x, y) {
		this.droids.push(new Faller(x, y, 0, 0, x, y, [], this, null));
	};

	this.removeDroid = function(droid) {
		for ( var i = 0; i < this.droids.length; i++) {
			if (this.droids[i] === droid) {
				this.droids[i] = this.droids[this.droids.length - 1];
				this.droids.pop();
				break;
			}
			;
		}
	};

	this.setSelected = function(x, y) {
		this.selectedX = x;
		this.selectedY = y;
	};

	this.getSelectedDroid = function() {
		for ( var i = 0; i < this.droids.length; i++) {
			if (this.droids[i].selected) {
				return this.droids[i];
			}
		}
		return null;
	};

	this.init();
}
